package com.application.lucky.request.nav;

import android.support.annotation.NonNull;
import android.text.TextUtils;


import com.alibaba.fastjson.TypeReference;
import com.application.lucky.BuildConfig;
import com.application.lucky.Lucky;
import com.application.lucky.bean.eventbean.ForceUpgradeEvent;
import com.application.lucky.bean.sqliteBean.HostUrlData;
import com.application.lucky.request.CallBackEx;
import com.application.lucky.utils.JsonParserUtil;
import com.application.lucky.utils.NetWorkUtil;
import com.application.mylibrary.bean.jsonbean.SystemConfigEntity;
import com.application.mylibrary.config.Common;
import com.application.mylibrary.utils.EventBusUtils;
import com.application.mylibrary.utils.ISharedPrefUtils;
import com.application.mylibrary.utils.LogUtils;
import com.baselib.libnetwork.net.libnetworkcomponent.BaseResponse;
import com.baselib.libnetwork.net.model.ResultResponse;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * @author lixiaoyu
 * @version v1.0
 * @description
 * @since 2017/10/23
 */

public class FrontEndProcessor {

    public void getConfig(final FrontEndProcessorCallback frontEndProcessorCallback) {
        LogUtils.i("FrontEndProcessor" + "开始getConfig");

        getLocalHost(frontEndProcessorCallback);

        if (NetWorkUtil.available()) {
            String navVersion = ISharedPrefUtils.getPref(Lucky.getApplication()).getStringValue(Common.NavVersion);
            new FrontEndRequest().getConfig("v", navVersion, new CallBackEx<BaseResponse<SystemConfigEntity>>() {
                @Override
                public void onFailed(int code) {

                }

                @Override
                public void onException(ResultResponse<BaseResponse<SystemConfigEntity>> response) {

                }

                @Override
                public void onSuccess(BaseResponse<SystemConfigEntity> rsp) {
                    if (rsp != null && rsp.dataInfo != null) {
                        cacheConfig(rsp.dataInfo);

                        if (rsp.dataInfo.force_upgrade) {
                            EventBusUtils.postSticky(new ForceUpgradeEvent());
                        }
                    }
                }
            });
        }
    }

    private void getLocalHost(final FrontEndProcessorCallback frontEndProcessorCallback) {
        List<HostUrlData> list = Lucky.getApplication().getDaoSession()
                .getHostUrlDataDao().getSession().queryBuilder(HostUrlData.class).list();
        LogUtils.e("getLocalHost ----- start");
        if (list != null && list.size() > 0) {
            Observable
                    .just(list)
                    .subscribeOn(Schedulers.io())
                    .map(new Function<List<HostUrlData>, Map<String, String>>() {
                        @Override
                        public Map<String, String> apply(List<HostUrlData> hostUrlData) throws Exception {
                            Map<String, String> m = new HashMap<>();
                            for (HostUrlData hostUrlDatum : hostUrlData) {
                                m.put(hostUrlDatum.getUrlName(), hostUrlDatum.getUrlValue());
                            }
                            return m;
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Map<String, String>>() {
                        @Override
                        public void accept(Map<String, String> navs) throws Exception {
                            UrlManager.put(navs);

                            if (frontEndProcessorCallback != null) {
                                frontEndProcessorCallback.success();
                            }
                        }
                    });
        } else {
            Observable<String> nav;
            if (!BuildConfig.DEBUG) {
                nav = Observable.just(getFromAssets("nav_online"));
            } else {
                nav = Observable.just(getFromAssets("nav_offline"));
            }
            LogUtils.e("getLocalHost -----  " + BuildConfig.ENVIRONMENT);
            nav.subscribeOn(Schedulers.io())
                    .map(new Function<String, SystemConfigEntity>() {
                        @Override
                        public SystemConfigEntity apply(String s) throws Exception {
                            LogUtils.e("getLocalHost apply -----  " + s);
                            if (TextUtils.isEmpty(s)) {
                                return null;
                            } else {
                                TypeReference<BaseResponse<SystemConfigEntity>> typeReference = new TypeReference<BaseResponse<SystemConfigEntity>>() {
                                };

                                LogUtils.e("getLocalHost apply -----  " + typeReference.getType().toString());
                                BaseResponse<SystemConfigEntity> baseResponse = JsonParserUtil.getBean(s, typeReference);
                                LogUtils.e("getLocalHost apply -----  " + baseResponse);
                                SystemConfigEntity dataInfo = baseResponse.dataInfo;
                                LogUtils.e("getLocalHost apply -----  " + dataInfo);
                                return dataInfo;
                            }
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<SystemConfigEntity>() {
                        @Override
                        public void accept(SystemConfigEntity systemConfigEntity) throws Exception {
                            if (systemConfigEntity != null) {
                                cacheConfig(systemConfigEntity);
                                if (frontEndProcessorCallback != null) {
                                    frontEndProcessorCallback.success();
                                }
                            }
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            LogUtils.e("getLocalHost -----  exception");
                            LogUtils.e(throwable.getMessage());
                        }
                    });
        }
    }


    public String getFromAssets(String fileName) {
        String Result = "";
        try {
            InputStreamReader inputReader = new InputStreamReader(Lucky.getApplication().getResources().getAssets().open(fileName));
            BufferedReader bufReader = new BufferedReader(inputReader);
            String line;
            while ((line = bufReader.readLine()) != null) {
                Result += line;
            }
            inputReader.close();
            bufReader.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return Result;
        }
    }

    /**
     * 数据存储
     *
     * @param dataInfo
     */
    private void cacheConfig(SystemConfigEntity dataInfo) {
        Map<String, String> navs = dataInfo.navs;
        if (navs != null && navs.size() > 0) {
            UrlManager.put(dataInfo.navs);
            navsUrl(dataInfo.navs);
        }
    }

    /**
     * Url存储
     * 入库前删除库内已有数据，不然会出现重复插入Exception
     */
    private void navsUrl(Map<String, String> navs) {
        Observable
                .fromIterable(navs.entrySet())
                .subscribeOn(Schedulers.newThread())
                .map(new Function<Map.Entry<String, String>, HostUrlData>() {
                    @Override
                    public HostUrlData apply(@NonNull Map.Entry<String, String> entry) throws Exception {
                        return new HostUrlData(entry.getKey(), entry.getValue());
                    }
                })
                .toList()
                .observeOn(Schedulers.io())
                .subscribe(new Consumer<List<HostUrlData>>() {
                               @Override
                               public void accept(List<HostUrlData> hostUrlData) throws Exception {
                                   try {
                                       //数据库满了  crash
                                       Lucky.getApplication().getDaoSession()
                                               .getHostUrlDataDao()
                                               .insertOrReplaceInTx(hostUrlData);
                                   } catch (Exception e) {

                                   }

                               }
                           }
                        , new Consumer<Throwable>() {
                            @Override
                            public void accept(Throwable throwable) throws Exception {
                                LogUtils.i(throwable.getMessage());
                            }
                        });
    }


    public interface FrontEndProcessorCallback {
        void success();
    }


}
